module directx.dxgi;

public import directx.dxgitype;
public import directx.com;
alias directx.com.uuidof uuidof;

enum {
	DXGI_CPU_ACCESS_NONE		=  0,
	DXGI_CPU_ACCESS_DYNAMIC		=  1,
	DXGI_CPU_ACCESS_READ_WRITE	=  2,
	DXGI_CPU_ACCESS_SCRATCH		=  3,
	DXGI_CPU_ACCESS_FIELD		= 15
}

enum {
	DXGI_USAGE_SHADER_INPUT			= 0b00_00010000,
	DXGI_USAGE_RENDER_TARGET_OUTPUT	= 0b00_00100000,
	DXGI_USAGE_BACK_BUFFER			= 0b00_01000000,
	DXGI_USAGE_SHARED				= 0b00_10000000,
	DXGI_USAGE_READ_ONLY			= 0b01_00000000,
	DXGI_USAGE_DISCARD_ON_PRESENT	= 0b10_00000000,
}
alias UINT DXGI_USAGE;

struct DXGI_FRAME_STATISTICS {
	UINT PresentCount;
	UINT PresentRefreshCount;
	UINT SyncRefreshCount;
	LARGE_INTEGER SyncQPCTime;
	LARGE_INTEGER SyncGPUTime;
}

struct DXGI_MAPPED_RECT {
	INT Pitch;
	BYTE* pBits;
}

struct DXGI_ADAPTER_DESC {
	WCHAR[128] Description;
	UINT VendorId;
	UINT DeviceId;
	UINT SubSysId;
	UINT Revision;
	SIZE_T DedicatedVideoMemory;
	SIZE_T DedicatedSystemMemory;
	SIZE_T SharedSystemMemory;
	LUID AdapterLuid;
}

struct DXGI_OUTPUT_DESC {
	WCHAR[32] DeviceName;
	RECT DesktopCoordinates;
	BOOL AttachedToDesktop;
	DXGI_MODE_ROTATION Rotation;
	HMONITOR Monitor;
}

struct DXGI_SHARED_RESOURCE {
	HANDLE Handle;
}

enum {
	DXGI_RESOURCE_PRIORITY_MINIMUM	= 0x28000000,
	DXGI_RESOURCE_PRIORITY_LOW		= 0x50000000,
	DXGI_RESOURCE_PRIORITY_NORMAL	= 0x78000000,
	DXGI_RESOURCE_PRIORITY_HIGH		= 0xa0000000,
	DXGI_RESOURCE_PRIORITY_MAXIMUM	= 0xc8000000
}

enum DXGI_RESIDENCY {
	DXGI_RESIDENCY_FULLY_RESIDENT				= 1,
	DXGI_RESIDENCY_RESIDENT_IN_SHARED_MEMORY	= 2,
	DXGI_RESIDENCY_EVICTED_TO_DISK				= 3
}

struct DXGI_SURFACE_DESC {
	UINT Width;
	UINT Height;
	DXGI_FORMAT Format;
	DXGI_SAMPLE_DESC SampleDesc;
}

enum DXGI_SWAP_EFFECT {
	DXGI_SWAP_EFFECT_DISCARD	= 0,
	DXGI_SWAP_EFFECT_SEQUENTIAL	= 1
}

enum DXGI_SWAP_CHAIN_FLAG {
	DXGI_SWAP_CHAIN_FLAG_NONPREROTATED		= 1,
	DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH	= 2
}

struct DXGI_SWAP_CHAIN_DESC {
	DXGI_MODE_DESC BufferDesc;
	DXGI_SAMPLE_DESC SampleDesc;
	DXGI_USAGE BufferUsage;
	UINT BufferCount;
	HWND OutputWindow;
	BOOL Windowed;
	DXGI_SWAP_EFFECT SwapEffect;
	UINT Flags;
}


mixin( uuid!(IDXGIObject, "aec22fb8-76f3-4639-9be0-28eb43a67a2e"));
interface IDXGIObject : IUnknown {
	extern(Windows) :
	HRESULT SetPrivateData(REFGUID Name, UINT DataSize, void* pData);
	HRESULT SetPrivateDataInterface(REFGUID Name, IUnknown pUnknown);
	HRESULT GetPrivateData(REFGUID Name, UINT* pDataSize, void* pData);
	HRESULT GetParent(REFIID riid, void** ppParent);
}

mixin( uuid!(IDXGIDeviceSubObject, "3d3e0379-f9de-4d58-bb6c-18d62992f1a6"));
interface IDXGIDeviceSubObject : IDXGIObject {
	extern(Windows) :
	HRESULT GetDevice(REFIID riid, void** ppDevice);
}

mixin( uuid!(IDXGIResource, "035f3ab4-482e-4e50-b41f-8a7f8bd8960b"));
interface IDXGIResource : IDXGIDeviceSubObject {
	extern(Windows) :
	HRESULT GetSharedHandle(HANDLE* pSharedHandle);
	HRESULT GetUsage(DXGI_USAGE* pUsage);
	HRESULT SetEvictionPriority(UINT EvictionPriority);
	HRESULT GetEvictionPriority(UINT* pEvictionPriority);
}


mixin( uuid!(IDXGIKeyedMutex, "9d8e1289-d7b3-465f-8126-250e349af85d"));
interface IDXGIKeyedMutex : IDXGIDeviceSubObject
{
    extern(Windows) :
    HRESULT AcquireSync( 
        UINT64 Key,
        DWORD dwMilliseconds);
        
    HRESULT ReleaseSync( 
        UINT64 Key);
}

mixin( uuid!(IDXGISurface, "cafcb56c-6ac3-4889-bf47-9e23bbd260ec"));
interface IDXGISurface : IDXGIDeviceSubObject {
	extern(Windows) :
	HRESULT GetDesc(DXGI_SURFACE_DESC* pDesc);
	HRESULT Map(DXGI_MAPPED_RECT* pLockedRect, UINT MapFlags);
	HRESULT Unmap();
}

mixin( uuid!(IDXGISurface1, "4AE63092-6327-4c1b-80AE-BFE12EA32B86"));
interface IDXGISurface1 : IDXGISurface
{
    extern(Windows):
    HRESULT GetDC( 
        BOOL Discard,
        HDC *phdc);
        
    HRESULT ReleaseDC( 
        RECT *pDirtyRect);
};

mixin( uuid!(IDXGIAdapter, "2411e7e1-12ac-4ccf-bd14-9798e8534dc0"));
interface IDXGIAdapter : IDXGIObject {
	extern(Windows) :
	HRESULT EnumOutputs(UINT Output, IDXGIOutput* ppOutput);
	HRESULT GetDesc(DXGI_ADAPTER_DESC* pDesc);
	HRESULT CheckInterfaceSupport(REFGUID InterfaceName, LARGE_INTEGER* pUMDVersion);
}

mixin( uuid!(IDXGIOutput, "ae02eedb-c735-4690-8d52-5a8dc20213aa"));
interface IDXGIOutput : IDXGIObject {
	extern(Windows) :
	HRESULT GetDesc(DXGI_OUTPUT_DESC* pDesc);
	HRESULT GetDisplayModeList(DXGI_FORMAT EnumFormat, UINT Flags, UINT* pNumModes, DXGI_MODE_DESC* pDesc);
	HRESULT FindClosestMatchingMode(DXGI_MODE_DESC* pModeToMatch, DXGI_MODE_DESC* pClosestMatch, IUnknown pConcernedDevice);
	HRESULT WaitForVBlank();
	HRESULT TakeOwnership(IUnknown pDevice, BOOL Exclusive);
	void ReleaseOwnership();
	HRESULT GetGammaControlCapabilities(DXGI_GAMMA_CONTROL_CAPABILITIES* pGammaCaps);
	HRESULT SetGammaControl(DXGI_GAMMA_CONTROL* pArray);
	HRESULT GetGammaControl(DXGI_GAMMA_CONTROL* pArray);
	HRESULT SetDisplaySurface(IDXGISurface pScanoutSurface);
	HRESULT GetDisplaySurfaceData(IDXGISurface pDestination);
	HRESULT GetFrameStatistics(DXGI_FRAME_STATISTICS* pStats);
}

const DXGI_MAX_SWAP_CHAIN_BUFFERS = 16;

enum {
	DXGI_PRESENT_TEST				= 0x00000001,
	DXGI_PRESENT_DO_NOT_SEQUENCE	= 0x00000002,
	DXGI_PRESENT_RESTART			= 0x00000004
}

mixin( uuid!(IDXGISwapChain, "310d36a0-d2e7-4c0a-aa04-6a9d23b8886a"));
interface IDXGISwapChain : IDXGIDeviceSubObject {
	extern(Windows) :
	HRESULT Present(UINT SyncInterval, UINT Flags);
	HRESULT GetBuffer(UINT Buffer, REFIID riid, void** ppSurface);
	HRESULT SetFullscreenState(BOOL Fullscreen, IDXGIOutput pTarget);
	HRESULT GetFullscreenState(BOOL* pFullscreen, IDXGIOutput* ppTarget);
	HRESULT GetDesc(DXGI_SWAP_CHAIN_DESC* pDesc);
	HRESULT ResizeBuffers(UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags);
	HRESULT ResizeTarget(DXGI_MODE_DESC* pNewTargetParameters);
	HRESULT GetContainingOutput(IDXGIOutput* ppOutput);
	HRESULT GetFrameStatistics(DXGI_FRAME_STATISTICS* pStats);
	HRESULT GetLastPresentCount(UINT* pLastPresentCount);
}

const DXGI_MWA_NO_WINDOW_CHANGES =     ( 1 << 0 );
const DXGI_MWA_NO_ALT_ENTER =          ( 1 << 1 );
const DXGI_MWA_NO_PRINT_SCREEN =       ( 1 << 2 );
const DXGI_MWA_VALID =                 ( 0x7 );


mixin( uuid!(IDXGIFactory, "7b7166ec-21c7-44ae-b21a-c9ae321ae369"));
interface IDXGIFactory : IDXGIObject {
	extern(Windows) :
	HRESULT EnumAdapters(UINT Adapter, IDXGIAdapter* ppAdapter);
	HRESULT MakeWindowAssociation(HWND WindowHandle, UINT Flags);
	HRESULT GetWindowAssociation(HWND* pWindowHandle);
	HRESULT CreateSwapChain(IUnknown pDevice, DXGI_SWAP_CHAIN_DESC* pDesc, IDXGISwapChain* ppSwapChain);
	HRESULT CreateSoftwareAdapter(HMODULE Module, IDXGIAdapter* ppAdapter);
}


extern(Windows){
    HRESULT CreateDXGIFactory(
      const (IID)*riid,
      void* ppFactory
    );    
    
    HRESULT CreateDXGIFactory1(
      const (IID)*riid,
      void* ppFactory
    );    

}

mixin( uuid!(IDXGIDevice, "54ec77fa-1377-44e6-8c32-88fd5f44c84c"));
interface IDXGIDevice : IDXGIObject {
	extern(Windows) :
	HRESULT GetAdapter(IDXGIAdapter* pAdapter);
	HRESULT CreateSurface(DXGI_SURFACE_DESC* pDesc, UINT NumSurfaces, DXGI_USAGE Usage, DXGI_SHARED_RESOURCE* pSharedResource, IDXGISurface* ppSurface);
	HRESULT QueryResourceResidency(IUnknown* ppResources, DXGI_RESIDENCY* pResidencyStatus, UINT NumResources);
	HRESULT SetGPUThreadPriority(INT Priority);
	HRESULT GetGPUThreadPriority(INT* pPriority);
}

enum DXGI_ADAPTER_FLAG{
	DXGI_ADAPTER_FLAG_NONE	= 0,
	DXGI_ADAPTER_FLAG_REMOTE	= 1,
	DXGI_ADAPTER_FLAG_FORCE_DWORD	= 0xffffffff
}

struct DXGI_ADAPTER_DESC1
{
    WCHAR[128] Description;
    UINT VendorId;
    UINT DeviceId;
    UINT SubSysId;
    UINT Revision;
    SIZE_T DedicatedVideoMemory;
    SIZE_T DedicatedSystemMemory;
    SIZE_T SharedSystemMemory;
    LUID AdapterLuid;
    UINT Flags;
}

struct DXGI_DISPLAY_COLOR_SPACE
{
    FLOAT[8][2] PrimaryCoordinates;
    FLOAT[16][2] WhitePoints;
}

    mixin( uuid!(IDXGIFactory1, "770aae78-f26f-4dba-a829-253c83d1b387"));
    interface IDXGIFactory1 : IDXGIFactory
    {
        extern(Windows) :
        HRESULT EnumAdapters1( 
            UINT Adapter,
            IDXGIAdapter1 *ppAdapter);
        
        BOOL IsCurrent();
    }
    
    
mixin( uuid!(IDXGIAdapter1, "29038f61-3839-4626-91fd-086879011a05"));
interface IDXGIAdapter1 : IDXGIAdapter
{
    extern(Windows):
    HRESULT GetDesc1( DXGI_ADAPTER_DESC1 *pDesc);
}
    
mixin( uuid!(IDXGIDevice1, "77db970f-6276-48ba-ba28-070143b4392c"));
interface IDXGIDevice1 : IDXGIDevice
{
    extern(Windows):
    HRESULT SetMaximumFrameLatency( UINT MaxLatency );
        
    HRESULT GetMaximumFrameLatency( UINT *pMaxLatency);
}


